package com.bodu.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bodu.core.entity.ParamReq;
import com.bodu.core.entity.enums.DelFlagEnum;
import com.bodu.core.entity.enums.StatusFlagEnum;
import com.bodu.system.entity.po.AreaPo;
import com.bodu.system.entity.po.DeptPo;
import com.bodu.system.entity.request.DeptRequest;
import com.bodu.system.entity.vo.DeptVo;
import com.bodu.system.mapper.AreaMapper;
import com.bodu.system.mapper.DeptMapper;
import com.bodu.system.service.DeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author r.guo
 * @since 2019-05-25
 */
@Service("deptService")
public class DeptServiceImpl implements DeptService {

    /**
     * 最高编号
     */
    private final static Long ROOT_ID = -1L;

    @Resource
    private DeptMapper deptMapper;

    @Resource
    private AreaMapper areaMapper;

    @Override
    public DeptVo getModel(Long id) {
        return deptMapper.getModel(id);
    }

    @Override
    public Long save(DeptRequest request) {
        if (ObjectUtil.isEmpty(request.getParentId())) {
            request.setParentId(-1L);
        }
        return deptMapper.save(request);
    }

    @Override
    public Long update(DeptRequest request) {
        return deptMapper.update(request);
    }

    @Override
    public List<DeptVo> listPage(ParamReq<DeptRequest> params) {
        return deptMapper.listPage(params);
    }

    @Override
    public Integer countPage(ParamReq<DeptRequest> params) {
        return deptMapper.countPage(params);
    }

    @Override
    public Integer updateDelFlagById(Long id, Integer delFlag) {
        return deptMapper.updateDelFlagById(id, delFlag);
    }

    @Override
    public List<DeptVo> loopList() {
        ParamReq<DeptRequest> req = new ParamReq<>();
        DeptRequest deptRequest = new DeptRequest();
        deptRequest.setDelFlag(DelFlagEnum.NO.getValue());
        req.setEntity(deptRequest);
        Integer total = countPage(req);
        req.setSize(total);
        List<DeptVo> permits = listPage(req);
        return getChildren(permits, ROOT_ID);
    }

    @Override
    public List<DeptVo> storeLists(String openid) {
        ParamReq<DeptRequest> req = new ParamReq<>();
        DeptRequest deptRequest = new DeptRequest();
        deptRequest.setDelFlag(DelFlagEnum.NO.getValue());
        deptRequest.setStatusFlag(StatusFlagEnum.USE.getValue());
        req.setEntity(deptRequest);
        Integer total = countPage(req);
        req.setSize(total);
        return listPage(req);
    }

    @Override
    public List<DeptVo> getChildByParentId(Long parentId, Integer statusFlag) {
        List<DeptPo> depts = deptMapper.getChildByParentId(parentId, statusFlag);
        List<DeptVo> deptVo = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(depts)) {
            depts.forEach(deptPo -> {
                DeptVo inDeptvo = new DeptVo();
                BeanUtils.copyProperties(deptPo, inDeptvo);
                deptVo.add(inDeptvo);
            });
        }
        return deptVo;
    }

    @Override
    public Set<Long> getDeptIdsByDept(Long deptId) {
        ParamReq<DeptRequest> req = new ParamReq<>();
        DeptRequest deptRequest = new DeptRequest();
        deptRequest.setDelFlag(DelFlagEnum.NO.getValue());
        req.setEntity(deptRequest);
        List<DeptVo> allDepts = deptMapper.listPage(req);
        Set<Long> deptIds = CollUtil.newHashSet();
        loopDept(deptId, allDepts, deptIds);
        return deptIds;
    }


    private void loopDept(Long deptId, List<DeptVo> deptList, Set<Long> deptIds) {
        deptIds.add(deptId);
        for (DeptVo p : deptList) {
            if (p.getParentId().equals(deptId)) {
                loopDept(p.getId(), deptList, deptIds);
            }
        }
    }


    private DeptVo loopPermits(DeptVo deptVo, List<DeptVo> deptLists) {
        List<DeptVo> chidren = getChildren(deptLists, deptVo.getId());
        deptVo.setChildren(chidren);
        return deptVo;
    }

    /**
     * @param depts    单位集合
     * @param parentId 父类菜单编号
     * @return jihe
     */
    private List<DeptVo> getChildren(List<DeptVo> depts, Long parentId) {
        List<DeptVo> chidren = CollUtil.newArrayList();
        for (DeptVo p : depts) {
            p.setProvinceName(getAreaName(p.getProvince()));
            p.setCityName(getAreaName(p.getCity()));
            p.setDistrictName(getAreaName(p.getDistrict()));
            if (ObjectUtil.isNotEmpty(p.getParentId()) && p.getParentId().equals(parentId)) {
                chidren.add(loopPermits(p, depts));
            }
        }
        return chidren;
    }

    /**
     * 得到Area Name
     *
     * @return
     */
    private String getAreaName(Long code) {
        if (ObjectUtil.isNotEmpty(code)) {
            AreaPo areaPo = areaMapper.findByCode(code, DelFlagEnum.NO.getValue());
            if (ObjectUtil.isNotEmpty(areaPo)) {
                return areaPo.getAreaName();
            }
        }
        return null;
    }
}
